package di

import (
	"fmt"
	"go.uber.org/dig"
)

var container = dig.New()

func Container() *dig.Container {
	return container
}

func MustGet[T any]() T {
	var res T
	MustInvoke(func(srv T) {
		res = srv
	})
	return res
}

func Invoke(function interface{}, opts ...dig.InvokeOption) error {
	err := container.Invoke(function, opts...)
	if err != nil {
		return fmt.Errorf("failed to invoke deps: %w", err)
	}
	return nil
}

func MustInvoke(function interface{}, opts ...dig.InvokeOption) {
	if err := container.Invoke(function, opts...); err != nil {
		panic(err)
	}
}

func Provide(constructor interface{}, opts ...dig.ProvideOption) error {
	err := container.Provide(constructor, opts...)
	if err != nil {
		return fmt.Errorf("failed to provide deps: %w", err)
	}
	return nil
}

func MustProvide(constructor interface{}, opts ...dig.ProvideOption) {
	if err := container.Provide(constructor, opts...); err != nil {
		panic(err)
	}
}

func MustProvides(constructors ...interface{}) {
	for _, constructor := range constructors {
		if err := container.Provide(constructor); err != nil {
			panic(err)
		}
	}
}
